import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// mysqldump --skip-triggers --compact --no-create-info  -u root -p AuditApplication
//    --extended-insert=FALSE --skip-quote-names --hex-blob --tables  > ~/Desktop/amrs.sql

// export CLASSPATH=.:/Users/leonardo/myWorkspaces/default/mysql2ingres/bin/mysql-connector-java-5.1.8-bin.jar 

public class IngresInsert {
	private Connection conn;
	private Date dtInit;
	private Date dtEnd;
	int i = 0;
	int bufSize = 500;
	private Properties properties = new Properties();
	private static Properties bigNames = new Properties();

	public static void main(String[] args) throws Exception {
		bigNames.load(new FileInputStream("bigNames.properties"));
		/*
		Set<Entry<Object, Object>> set = bigNames.entrySet();
		for (Entry<Object, Object> entry : set) {
			System.out.print("" + entry.getKey() + " - " + entry.getValue());
		}
		*/
		if (args.length == 0) {
			new IngresInsert().insert("");
		} else {
			new IngresInsert().insert(args[0]);
		}

	}

	private String replaceBigName(String strLine) {
		Pattern p1 = Pattern.compile("INSERT INTO ");
		Matcher m1 = p1.matcher(strLine);
		int ini = 0;
		int end = 0;
		if (m1.find()) {
			ini = m1.end();
		}

		Pattern p2 = Pattern.compile(" VALUES");
		Matcher m2 = p2.matcher(strLine);
		if (m2.find()) {
			end = m2.start();
		}
		String table = strLine.substring(ini, end);
		if (table.length() > 32) {
			strLine = strLine.replace(table, bigNames.getProperty(table));
		}

		return strLine;
	}

	public void insert(String fileName) throws Exception {
		// String fileName = ;
		if (fileName == null || fileName.equals("")) { // Default
			fileName = "/Users/leonardo/Desktop/amrs.sql";
			// fileName = "/Users/leonardo/Desktop/RevisitMeter.sql";
		} else {
			System.out.println("### Using file: " + fileName);
		}
		System.out.println("### Init reading...");
		try {
			FileInputStream fstream = new FileInputStream(fileName);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;

			Statement stm = conn.createStatement();
			dtInit = new Date();
			System.out.println("$$$ Init: " + dtInit);

			conn.setAutoCommit(false);
			long totloop = 0;
			while ((strLine = br.readLine()) != null) {
				strLine = strLine.substring(0, strLine.length() - 1);
				 strLine = strLine.replace("\\'", "''"); //Eto'o ...

				//strLine = replaceBigName(strLine); //Tables should be renamed before... too slow

				//System.out.println(strLine);
				stm.addBatch(strLine);
				i++;
				if (i == bufSize) {
					stm.executeBatch();
					conn.commit();
					long diff = new Date().getTime() - dtInit.getTime();
					totloop++;
					System.out.println("@@@@@@@@@@@@@@@@@ Flushing: " + i
							+ " lines. Seq: " + totloop + " Tot Time(m): "
							+ (diff / 1000) / 60);
					i = 0;
				}
			}
			stm.executeBatch();
			conn.commit();
			System.out.println("@@@@@@@@@@@@@@@@@ Last Flush: " + i + " lines");

			in.close();
			System.out.println("$$$ End: " + new Date());
			long diff = new Date().getTime() - dtInit.getTime();
			System.out.println("$$$ TOTAL(sec): " + diff / 1000);
			System.out.println("$$$ TOTAL(min): " + (diff / 1000) / 60);

		} catch (Exception e) {
			System.err.println("Error: " + e.getMessage());
			conn.rollback();
		} finally {
			conn.close();
		}

	}

	public IngresInsert() {

		try {
			properties.load(new FileInputStream("config.properties"));
			String ingresTarget = properties.getProperty("ingresTarget");
			String buffer = properties.getProperty("bufSize");
			if (buffer != null && !buffer.equals("")) {
				bufSize = Integer.parseInt(buffer);
			}

			Class.forName("com.ingres.jdbc.IngresDriver");
			conn = DriverManager
					.getConnection(ingresTarget, "ingres", "ingres");
			System.out.println("### Setting Ingres Conn...");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}
